home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
3_0
/
CUTILSLI
/
UTILITYL
/
HELP.C
< prev
next >
Wrap
Text File
|
1987-11-10
|
13KB
|
448 lines
/**************************************************************************
* Filename: Help.c
* Purpose: Online Help with the List Manager
* Authors: Robert E. Neville from William Rausch's MacTutor example
* of April 1987.
* Date: November 5, 1987
* Functions: do_help(), read_help(),
* show_help(), help_filter(),
* help_action(), FileError().
* Version: 1.0
* Copyright: Hummingbird Graphics & Software
***************************************************************************/
#include <EventMgr.h>
#include <WindowMgr.h>
#include <ToolboxUtil.h>
#include <DialogMgr.h>
#include <FontMgr.h>
#include <ListMgr.h>
#include <strings.h>
#include <pascal.h>
#define HELPDLOG 301 /* Dialog RSRC for Help */
#define HELPOK 1 /* OK Button in HELPDLOG */
#define HELPBOX 3 /* Help List box RSRC */
#define HELPLIST 2 /* Where the Help Goes RSRC */
#define MAXHELPS 100 /* Maximum Help Items */
#define ACTIVATE 0
#define INACTIVATE 255
/* These must be redeclared elsewhere */
#define HELPSTR 600 /* STR# RSRC for Help*/
#define ERRORALERT 400 /* Error Alert RSRC */
struct
{
Rect text_box; /* User item dimensions */
Rect topic_box; /* User item dimensions */
TEHandle text; /* Text Edit Handle */
ListHandle topics; /* List Handle */
Rect d_rect; /* Destination Rect */
Rect v_rect; /* View Rect */
int offset; /* d_rect Vertical shift */
int lines_vis; /* Number of lines visible */
ControlHandle text_scroll; /* Control Handle */
int max_text; /* Max value of scroller */
int help_id[MAXHELPS]; /* Topics' HELP ID's */
int num_topics; /* Number of topics */
int last_one; /* Last cell clicked */
} helplist;
pascal Boolean help_filter();
Boolean show_help();
pascal void help_action();
/****************************************************************
* Function: do_help(str_id)
* Purpose: Present user with List of Topics and help
* text about each one. The Topics are stored
* as a STR# resource and the help texts are
* stored as HELP resources. Each topic
* string contains the number of its associated
* Help Resource. This function is the visible one.
* Passed: str_id - short
* Returned: Nothing.
*****************************************************************/
do_help(str_id)
short str_id;
{
DialogPtr the_dialog;
Handle scr_handle;
short scratch;
Str255 scr_str;
Rect hdata_rect;
Point cell_size;
Handle topics;
GrafPtr old_port;
char *Ferror = "returned an Error";
topics = GetResource('STR#', str_id);
helplist.num_topics = *(short *)(*topics);
the_dialog = GetNewDialog(HELPDLOG, 0L, -1L);
GetPort(&old_port);
SetPort(the_dialog);
GetDItem(the_dialog,
HELPLIST,
&scratch,
&scr_handle,
&helplist.topic_box);
InsetRect(&helplist.topic_box, 1, 1);
helplist.topic_box.right -= 15;
SetRect(&hdata_rect,0,0,1,helplist.num_topics);
SetPt(&cell_size, helplist.topic_box.right - helplist.topic_box.left, 16);
helplist.topics = LNew(&helplist.topic_box,
&hdata_rect,
cell_size,
0,
the_dialog,
FALSE,
FALSE,
FALSE,
TRUE);
(*helplist.topics)->selFlags = lOnlyOne;
InsetRect(&helplist.topic_box, -1, -1);
read_help(helplist.topics,helplist.num_topics,helplist.help_id,str_id);
if ( !show_help(the_dialog,helplist.topics,helplist.help_id) )
FileError("\pshow_help(), ", Ferror);
SetPort(old_port);
} /* End of do_help */
/************************************************************
* Function: read_help(topics,num_topics,help_id,str_id)
* Purpose: Read the topics from STR# RSRC. Add them to
* the List as they are read. Also save the ID's
* in an array for use later in finding the
* proper HELP RSRC to display for each topic.
* Passed: topics - List Handle
* num_topics - SHORT
* help_id - Ptr to SHORT array
* str_id - SHORT
* Returned: Nothing.
*************************************************************/
read_help(topics,num_topics,help_id,str_id)
ListHandle topics;
short num_topics;
short help_id[];
short str_id;
{
short i;
Str255 a_topic;
Point the_cell;
char *id_number;
Str255 strvar;
for ( i = 0; i < num_topics; i++ )
{
GetIndString(a_topic,str_id, i + 1);
PtoCstr(a_topic);
id_number = strchr(a_topic, (char)'\\');
*id_number++ = '\0';
help_id[i] = atoi(id_number);
SetPt(&the_cell, 0, i);
LSetCell(a_topic,strlen(a_topic), the_cell, topics);
}
SetPt(&the_cell, 0, 0);
LSetSelect((Boolean)TRUE, the_cell, topics);
LDoDraw((Boolean)TRUE, topics);
}
/************************************************************
* Function: show_help(the_dialog,topics,help_id)
* Purpose: Set up the help text for the first topic in
* the List. Call ModalDialog (with a filterproc)
* to do all the work. Loop until OK clicked.
* Passed: the_dialog - Dialog Ptr
* topics - List Handle
* help_id - Ptr to SHORT array
* Returned: TRUE
*************************************************************/
Boolean show_help(the_dialog,topics,help_id)
DialogPtr the_dialog;
ListHandle topics;
short help_id[];
{
GrafPtr old_port;
short item_hit;
short scr_int;
Handle scr_handle;
Boolean done = FALSE;
short i, buf_size;
Rect scroll_rect;
Handle the_help;
GetDItem(the_dialog, HELPBOX, &scr_int, &scr_handle, &helplist.text_box);
helplist.text_box.right -= 16;
scroll_rect.right = helplist.text_box.right + 15;
scroll_rect.left = helplist.text_box.right - 1;
scroll_rect.top = helplist.text_box.top;
scroll_rect.bottom = helplist.text_box.bottom;
helplist.text_scroll = NewControl(the_dialog,
&scroll_rect,
"",
TRUE,
0,
0,
0,
16,
0L);
HiliteControl(helplist.text_scroll, INACTIVATE);
helplist.d_rect.top = helplist.text_box.top + 1;
helplist.d_rect.left = helplist.text_box.left + 1;
helplist.d_rect.right = helplist.text_box.right - 1;
helplist.d_rect.bottom = 20000;
helplist.v_rect = helplist.text_box;
InsetRect(&helplist.v_rect, 1, 1);
helplist.text = TENew(&helplist.d_rect, &helplist.v_rect);
(*helplist.text)->txFont = systemFont;
(*helplist.text)->txSize = 12;
helplist.last_one = 0;
helplist.offset = 0;
helplist.lines_vis = (helplist.v_rect.bottom - helplist.v_rect.top)
/ (*helplist.text)->lineHeight;
the_help = GetResource('HELP',help_id[0]);
buf_size = SizeResource(the_help);
TEDeactivate(helplist.text);
TESetSelect(32767L,32767L,helplist.text);
HLock(the_help);
TEInsert(*the_help,(long)buf_size,helplist.text);
HUnlock(the_help);
if ( (*helplist.text)->nLines > helplist.lines_vis )
{
HiliteControl(helplist.text_scroll, ACTIVATE);
helplist.max_text = (((*helplist.text)->nLines)
- helplist.lines_vis)
* (*helplist.text)->lineHeight;
SetCtlMax(helplist.text_scroll, helplist.max_text);
}
ShowWindow(the_dialog);
do
{
ModalDialog(help_filter, &item_hit);
if (item_hit == HELPOK)
done = TRUE;
} while (!done);
TEDispose(helplist.text);
LDispose(helplist.topics);
DisposDialog(the_dialog);
return(TRUE);
} /* end of show_help */
/************************************************************
* Function: help_filter(dp,ep,ip)
* Purpose: Handle the activate and updating of the
* scroller and the box area. Handle mouseDowns
* in the scroller and text box, returning
* TRUE, and returning FALSE for everything else
* so the Dialog Manager does not abort.
* Passed: dp - Window Ptr
* ep - Ptr to Event Record
* ip - Ptr to SHORT
* Returned: TRUE - Mouse Downs in Scroller, text box
* FALSE - Everything else
*************************************************************/
pascal Boolean help_filter(dp,ep,ip)
WindowPtr dp;
EventRecord *ep;
short *ip;
{
short part;
ControlHandle ch;
char tempchar;
Point mouse_loc;
short delta;
long a_cell;
short cell_num;
Handle the_help;
short buf_size;
short scr_int;
Handle scr_handle;
Rect scr_rect;
switch (ep->what)
{
case updateEvt:
if (ep->message == (long)dp)
{
GetDItem(dp,HELPOK,&scr_int,&scr_handle,&scr_rect);
InsetRect(&scr_rect, -4,-4);
PenSize(3,3);
FrameRoundRect(&scr_rect, 16,16);
PenNormal();
FrameRect(&helplist.topic_box);
FrameRect(&helplist.text_box);
EraseRect(&helplist.v_rect);
TEUpdate(&helplist.v_rect, helplist.text);
LUpdate(dp->visRgn, helplist.topics);
}
return (FALSE);
case keyDown:
tempchar = BitAnd(ep->message, charCodeMask);
if (tempchar == '\r')
{
*ip = HELPOK;
return (TRUE);
}
return (FALSE);
case mouseDown:
mouse_loc = ep->where;
GlobalToLocal(&mouse_loc);
part = FindControl(mouse_loc, dp, &ch);
if (part > 0)
{
if (ch == helplist.text_scroll)
{
if (part == inThumb)
{
if (TrackControl(ch, mouse_loc, 0L))
{
delta = helplist.offset -
GetCtlValue(helplist.text_scroll);
TEScroll(0,delta, helplist.text);
helplist.offset -= delta;
}
}
else
TrackControl(ch,mouse_loc,help_action);
return (TRUE);
}
else if (ch == (*helplist.topics)->vScroll)
{
LClick(mouse_loc,ep->modifiers,helplist.topics);
return (TRUE);
}
else
return (FALSE);
}
else if (PtInRect(mouse_loc, *helplist.topics))
{
LClick(mouse_loc,ep->modifiers, helplist.topics);
a_cell = 0;
if (LGetSelect(TRUE, &a_cell, helplist.topics))
cell_num = HiWord(a_cell);
if (cell_num >= 0 && cell_num != helplist.last_one)
{
TEDeactivate(helplist.text);
TESetSelect(0L,32767L,helplist.text);
TEDelete(helplist.text);
if (cell_num < helplist.num_topics)
{
the_help = GetResource('HELP',
helplist.help_id[cell_num]);
buf_size = SizeResource(the_help);
}
else
buf_size = 0;
if (buf_size > 0)
{
HLock(the_help);
TEInsert(*the_help,(long)buf_size,helplist.text);
HUnlock(the_help);
}
SetCtlValue(helplist.text_scroll,0);
delta = helplist.offset - GetCtlValue(helplist.text_scroll);
TEScroll(0,delta,helplist.text);
helplist.offset -= delta;
if ((*helplist.text)->nLines > helplist.lines_vis)
{
HiliteControl(helplist.text_scroll,ACTIVATE);
helplist.max_text = (((*helplist.text)->nLines)
- helplist.lines_vis)
* (*helplist.text)->lineHeight;
SetCtlMax(helplist.text_scroll,helplist.max_text);
}
else
HiliteControl(helplist.text_scroll,INACTIVATE);
helplist.last_one = cell_num;
}
return (TRUE);
}
return (FALSE);
default:
return (FALSE);
}
} /* end of help_filter */
/************************************************************
* Function: help_action(the_scroll,partcode)
* Purpose: Routine called by Toolbox during TrackControl.
* Takes care of scrolling the text when the
* up/down arrow and page parts of scroll bar
* are clicked in.
* Passed: the_scroll - Control Handle
* partcode - short
* Returned: Nothing
*************************************************************/
pascal void help_action(the_scroll,partcode)
ControlHandle the_scroll;
short partcode;
{
short value, delta;
switch (partcode)
{
case inUpButton:
value = GetCtlValue(the_scroll);
value = (value - (*helplist.text)->lineHeight > 0)
? value - (*helplist.text)->lineHeight : 0;
SetCtlValue(the_scroll,value);
break;
case inPageUp:
value = GetCtlValue(the_scroll);
value = (value - 6 * (*helplist.text)->lineHeight > 0)
? value - 6 * (*helplist.text)->lineHeight : 0;
SetCtlValue(the_scroll,value);
break;
case inDownButton:
value = GetCtlValue(the_scroll);
value = (value + (*helplist.text)->lineHeight < helplist.max_text)
? value + (*helplist.text)->lineHeight : helplist.max_text;
SetCtlValue(the_scroll,value);
break;
case inPageDown:
value = GetCtlValue(the_scroll);
value = (value + 6 * (*helplist.text)->lineHeight
< helplist.max_text)
? value + 6 * (*helplist.text)->lineHeight
: helplist.max_text;
SetCtlValue(the_scroll,value);
break;
}
delta = helplist.offset - GetCtlValue(helplist.text_scroll);
TEScroll(0,delta,helplist.text);
helplist.offset -= delta;
} /* End of help_action */
/****************************************************************
* Function: FileError(str)
* Purpose: Issue Alert if Standard File goes Wrong.
* Passed: str1,str2 - Pascal String Ptr.
* Returned: Nothing.
*****************************************************************/
FileError(str1,str2)
char *str1; /* Ptr to String */
char *str2;
{
ParamText(str1, str2,"\p","\p"); /* pass string to ParamText */
NoteAlert(ERRORALERT, 0L); /* Issue Error Alert */
} /* End of FileError */
/********** End of file **********/